package graphicinterface;

import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.LinkedList;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.DefaultStyledDocument;

import bookworm.AdministratorOfAllBookTagsUsedByTheSystem;
import bookworm.Review;

/**
 * 
 * this UI will show a single review to the user
 *
 */
public class WindowShowSingleReview implements MouseListener
{
	/**
	 * review that the user will read in this window
	 */
	private Review reviewUserReads;
	private JFrame windowSingleReview;
	/**
	 * in the single review window, there will be buttons at the end of the page: each
	 * refers to a tag related to the book. By clicking in one button, the user will start a 
	 * search for books that match the tag selected.
	 */
	private LinkedList<JButton> buttonsRelatedTags;
	
	public WindowShowSingleReview(Review reviewToRead)
	{
		this.reviewUserReads = reviewToRead;
		this.windowSingleReview = new JFrameWithMenu(reviewToRead.getReviewTitle());
		this.drawWindowShowSingleReview();
	}
	
	private void drawWindowShowSingleReview()
	{
		//first, we'll create the components of the window
		//a panel with the initial info of the review(rating, book title, authors...)
		JPanel panelStartingReviewData = this.createPanelStartingReviewData();
		//a panel with the plain review text
		JPanel panelReviewText = this.createPanelReviewText();
		//a panel with the books's relatedTags
		JPanel panelRelatedTags = this.createpanelRelatedTags();
		
		//now let's join these panels in a single Jpanel!
		JPanel panelShowSingleReview = new JPanel();
		panelShowSingleReview.setBackground(new Color(255, 131, 137));
		GridBagLayout layoutPaneSingleReview = new GridBagLayout();
		panelShowSingleReview.setLayout(layoutPaneSingleReview);
		GridBagConstraints g = new GridBagConstraints();
		g.gridy = 0;
		g.gridheight = 3;
		panelShowSingleReview.add(panelStartingReviewData, g);
		g.gridy = 3;
		g.gridheight = 7;
		panelShowSingleReview.add(panelReviewText, g);
		
		g.gridy = 10;
		g.gridheight = 1;
		panelShowSingleReview.add(panelRelatedTags, g);
		
		//let''s add a scroll for this panel just in case the screen gets very big
		JScrollPane scroll = new JScrollPane(panelShowSingleReview);
		scroll.setVerticalScrollBarPolicy(
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
		scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		Dimension dimensionOfScreen = Toolkit.getDefaultToolkit().getScreenSize();
		scroll.setPreferredSize(dimensionOfScreen);
		scroll.setMinimumSize(dimensionOfScreen);
		
		//now let's add this panel in the frame
		this.windowSingleReview.add(scroll);
		this.windowSingleReview.setVisible(true);
	}
	
	
	/**
	 * creates a panel with the starting review data such as review title, review rating,
	 * book title, book authors,book medium cover...
	 * @return panel with starting review data
	 */
	private JPanel createPanelStartingReviewData()
	{
		String reviewTitle = this.reviewUserReads.getReviewTitle();
		JLabel labelReviewTitle = TextLabelCreator.createStyledTextlabel(reviewTitle, 30);
		int reviewRating = this.reviewUserReads.getRating();
		JLabel labelReviewRating =CreatesLabelWith5StarRating.createLabelWithStars(reviewRating);
		String mediumCoverAddress = this.reviewUserReads.getMediumCover();
		ImageIcon bookCover = GetsBookCoverByImageAddress.getBookCover(mediumCoverAddress);
		JLabel labelBookCover = new JLabel(bookCover);
		JPanel panelBookTitleAuthorAndReviewer = this.createPanelBookTitleAuthorAndReviewer();
		
		/*
		 * now that we have all the components for starting review data, let's put them together!
		 */
		JPanel panelStartingReviewData = new JPanel();
		panelStartingReviewData.setBackground(new Color(255, 131, 137));
		GridBagLayout layoutPanelStartingReviewData = new GridBagLayout();
		panelStartingReviewData.setLayout(layoutPanelStartingReviewData);
		GridBagConstraints g = new GridBagConstraints();
		g.gridy = 0;
		panelStartingReviewData.add(labelReviewTitle, g);
		g.gridy = 1;
		panelStartingReviewData.add(labelReviewRating, g);
		g.gridy = 2;
		g.gridheight = 2;
		panelStartingReviewData.add(labelBookCover, g);
		g.gridheight = 4;
		g.gridy = 4;
		panelStartingReviewData.add(panelBookTitleAuthorAndReviewer, g);
		
		return panelStartingReviewData;
		
	}
	
	/**
	 * creates a panel containing the book's title, author(s) and reviewer
	 * @return
	 */
	private JPanel createPanelBookTitleAuthorAndReviewer()
	{
		String bookTitle = this.reviewUserReads.getBookTitle();
		JLabel labelBookTitle = TextLabelCreator.createStyledTextlabel("book title:" + bookTitle, 20, new Color(119,112,250));
		LinkedList<String> bookAuthors = this.reviewUserReads.getAuthors();
		String labelTextBookAuthors = "Author:";
		if(bookAuthors.size() > 0)
		{
			labelTextBookAuthors = labelTextBookAuthors + bookAuthors.getFirst();
		}
		for(int i = 1; i < bookAuthors.size(); i++)
		{
			labelTextBookAuthors = labelTextBookAuthors + "," + bookAuthors.get(i);
		}
		JLabel labelBookAuthors = TextLabelCreator.createStyledTextlabel(labelTextBookAuthors, 20, new Color(119,112,250));
		String reviewerName = this.reviewUserReads.getReviewer();
		JLabel labelReviewername = TextLabelCreator.createStyledTextlabel("reviewer:" + reviewerName, 20, new Color(119,112,250));
		JLabel reviewerRatingStars = createLabelWithRatingStarsOfReviewer(reviewerName);
		JLabel labelreviewerGrade = TextLabelCreator.createStyledTextlabel("reviewer rating:", 20, new Color(119,112,250));
		JPanel panelreviewerRatingAndStars = new JPanel();
		panelreviewerRatingAndStars.setBackground(new Color(255, 131, 137));
		panelreviewerRatingAndStars.add(labelreviewerGrade);
		panelreviewerRatingAndStars.add(reviewerRatingStars);
		
		//now, let's join everything in a panel!
		JPanel panelBookTitleAuthorAndReviewer = new JPanel();
		panelBookTitleAuthorAndReviewer.setBackground(new Color(255, 131, 137));
		GridBagLayout layoutpanel = new GridBagLayout();
		panelBookTitleAuthorAndReviewer.setLayout(layoutpanel);
		GridBagConstraints g = new GridBagConstraints();
		g.gridy = 0;
		panelBookTitleAuthorAndReviewer.add(labelBookTitle, g);
		g.gridy = 1;
		panelBookTitleAuthorAndReviewer.add(labelBookAuthors, g);
		g.gridy = 2;
		panelBookTitleAuthorAndReviewer.add(labelReviewername, g);
		g.gridy = 3;
		panelBookTitleAuthorAndReviewer.add(panelreviewerRatingAndStars, g);
		
		return panelBookTitleAuthorAndReviewer;
	}

	private JLabel createLabelWithRatingStarsOfReviewer(String reviewerName) 
	{
		//we'll ask for the reviewer's grade through facade.
		SystemFunctionalitiesFacade facade = SystemFunctionalitiesFacade.getInstance();
		//we need to give the reviewer name through list
		LinkedList<String> reviewernameInList = new LinkedList<String>();
		reviewernameInList.add(reviewerName);
		LinkedList<Integer> reviewerGradeInList = facade.getAllBookReviewersRatings(reviewernameInList);
		int reviewerGrade = reviewerGradeInList.getFirst();
		JLabel reviewerRatingStars = CreatesLabelWith5StarRating.createLabelWithStars(reviewerGrade);
		return reviewerRatingStars;
	}
	
	/**
	 * creates a JPanel simply with the review text from the Review instance this window works with.
	 * It won't contain the review's details, just the plain review text.
	 * @return panel with the plain review text associated with the Review instance.
	 */
	private JPanel createPanelReviewText()
	{
		JPanel panelReviewText = new JPanel();
		panelReviewText.setBackground(new Color(255, 131, 137));
		
		JPanel panelTextArea= new JPanel();
		//the panel structure in which we'll add the review text is a JTextPane
		JTextPane textPaneReviewText = new JTextPane(new DefaultStyledDocument());
		textPaneReviewText.setBackground(new Color(255, 131, 137));
		textPaneReviewText.setContentType("text/html");
		textPaneReviewText.setEditable(false);
		String stringReviewText = this.reviewUserReads.getReviewText();
		//we'll have to set the font style and color by HTML
		textPaneReviewText.setText("<font COLOR=\"#bd006f\" FACE=\"Showcard Gothic\">" + stringReviewText + "</font>");
		//let's add a scroll bar for the review text. It can get very big.
		JScrollPane scroll = new JScrollPane(textPaneReviewText);
		scroll.setVerticalScrollBarPolicy(
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
		scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		scroll.setPreferredSize(new Dimension(800, 200));
		scroll.setMinimumSize(new Dimension(800, 200));
		panelTextArea.add(scroll);
		
		panelReviewText.add(panelTextArea);
		
		
		return panelReviewText;
	}
	
	private JPanel createpanelRelatedTags()
	{
		this.buttonsRelatedTags = new LinkedList<JButton>();
		LinkedList<String> relatedTags = this.reviewUserReads.getTags();
		/*
		 * some of these tags our system doesn't work with. Let's filter this list to contain
		 * one tags our system can work with.
		 */
		LinkedList<String> relatedTagsValidForOurSystem = new LinkedList<String>();
		for(int j = 0; j < relatedTags.size(); j++)
		{
			String singleRelatedtag = relatedTags.get(j);
			if(AdministratorOfAllBookTagsUsedByTheSystem.isTagUsedByOurSystem(singleRelatedtag) == true)
			{
				relatedTagsValidForOurSystem.add(singleRelatedtag);
			}
		}
		for(int i = 0; i < relatedTagsValidForOurSystem.size(); i++)
		{
			String singleTag = relatedTagsValidForOurSystem.get(i);
			JGradientButton buttonForTag = new JGradientButton(singleTag);
			this.buttonsRelatedTags.add(buttonForTag);
			//these buttons can be clicked
			buttonForTag.addMouseListener(this);
		}
		
		//now, let's make a panel that joins all these buttons we just created!
		JPanel panelRelatedTags = new JPanel();
		panelRelatedTags.setBackground(new Color(255, 131, 137));
		for(int i = 0; i < buttonsRelatedTags.size(); i++)
		{
			JButton singleTagButton = this.buttonsRelatedTags.get(i);
			panelRelatedTags.add(singleTagButton);
		}
		//let's add a label to say that these buttons present related tags
		JLabel labelRelatedTags = TextLabelCreator.createStyledTextlabel("related tags:");
		//now we'll join this label with the panel with buttons(PanelRelatedTags)
		JPanel panelRelatedTagsWithLabel = new JPanel();
		panelRelatedTagsWithLabel.setBackground(new Color(255, 131, 137));
		GridLayout layoutPaneRelateTagsWithLabel = new GridLayout(2, 1);
		panelRelatedTagsWithLabel.setLayout(layoutPaneRelateTagsWithLabel);
		panelRelatedTagsWithLabel.add(labelRelatedTags);
		panelRelatedTagsWithLabel.add(panelRelatedTags);
		
		
		return panelRelatedTagsWithLabel;
	}

	@Override
	public void mouseClicked(MouseEvent e) 
	{
		//these user clicked something in the screen? it must be a button!
		JButton buttonUserClicked = this.getButtonUserJustClicked(e);
		if(buttonUserClicked != null)
		{
			//user really clicked on a button from window, not just some random clicking
			//first, let's change the cursor to a wait cursor because the following process takes a while
			Component objectEntered = e.getComponent();
			objectEntered.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
			String selectedTag = buttonUserClicked.getText();
			
			WindowBestBooksFromTag windowWithBooksFromTag = new WindowBestBooksFromTag(selectedTag);
			
			this.windowSingleReview.dispose();
		}
		
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
	
	/**
	 * based on a mouseEvent, it returns the button which the user just clicked or a null
	 * reference if the user clicked on another thing that wasn't a button.
	 * @param e mouseEvent representing the click of a user
	 * @return the button which the user just clicked OR a NULL object in case the user
	 * clicked on something that wasn't a valid button.
	 */
	public JButton getButtonUserJustClicked(MouseEvent e)
	{
		Object objectClicked = e.getSource();
		for(int i = 0; i < this.buttonsRelatedTags.size(); i++)
		{
			JButton buttonInWindow = this.buttonsRelatedTags.get(i);
			if(objectClicked == buttonInWindow)
			{
				return buttonInWindow;
			}
		}
		
		return null;//object clicked was not a valid button from or interface.
	}
	
	
	

}
